﻿using AutoMapper;
using FlyingEye.DeviceServices;
using FlyingEye.Exceptions;
using FlyingEye.SignalRHubs;
using FlyingEye.SignalRHubs.Requests;
using FlyingEye.SignalRHubs.TaskResults;
using Microsoft.AspNetCore.SignalR;
using Volo.Abp.Application.Services;
using Volo.Abp.Guids;

namespace FlyingEye.Services.SignalRHubs
{
    /// <summary>
    /// 设备客户端中心服务
    /// </summary>
    public class DeviceHubService : ApplicationService
    {
        private readonly IHubContext<DeviceHub, IDeviceClient> _hubContext;

        private readonly IMapper _mapper;

        private readonly IGuidGenerator _guidGenerator;

        private readonly DeviceResourceMapping _connectionMapping;

        private readonly DeviceClientService _deviceClientService;

        public DeviceHubService(IHubContext<DeviceHub, IDeviceClient> hubContext,
            IMapper mapper,
            IGuidGenerator guidGenerator,
            DeviceResourceMapping connectionMapping,
            DeviceConfigurationService configurationService,
            DeviceClientService deviceClientService)
        {

            _hubContext = hubContext;
            _mapper = mapper;
            _guidGenerator = guidGenerator;
            _connectionMapping = connectionMapping;
            _deviceClientService = deviceClientService;
        }

        /// <summary>
        /// 获取已连接的设备端的连接 id
        /// </summary>
        private string GetConnectionId(string resourceId)
        {
            if (!_connectionMapping.TryGetConnectionId(resourceId, out var connectionId))
            {
                throw new ResourceNotFoundException($"设备 id = {resourceId} 未连接！");
            }

            return connectionId;
        }

        /// <summary>
        /// 执行一个设备配置目标
        /// </summary>
        public async Task<DefaultResponse> ExecuteAsync(string resourceId)
        {
            var connectionId = GetConnectionId(resourceId);
            var configurations = await _deviceClientService.GetConfigurationsAsync(resourceId);

            if (configurations.Any())
            {
                return await _hubContext.Clients.Client(connectionId)
                    .ConfigAsync();
            }

            throw new ResourceNotFoundException($"设备 {resourceId} 未添加任何配置！");
        }

        /// <summary>
        /// 执行一个读取字符串的目标
        /// </summary>
        public async Task<ReadValueResponse> ExecuteAsync(string resourceId, ReadStringValueRequest request)
        {
            var connectionId = GetConnectionId(resourceId);

            return await _hubContext.Clients.Client(connectionId)
                .ReadStringValueAsync(request);
        }

        /// <summary>
        /// 执行一个读取值数据的目标
        /// </summary>
        public async Task<ReadValueResponse> ExecuteAsync(string resourceId, ReadNumericValueRequest request)
        {
            var connectionId = GetConnectionId(resourceId);

            return await _hubContext.Clients.Client(connectionId)
                .ReadNumericValueAsync(request);
        }

        /// <summary>
        /// 执行一个设备写入的目标
        /// </summary>
        public async Task<DefaultResponse> ExecuteAsync(string resourceId, WriteValueRequest request)
        {
            var connectionId = GetConnectionId(resourceId);

            return await _hubContext.Clients.Client(connectionId)
                .WriteValueAsync(request);
        }
    }
}
